package com.qf.air.service.impl;

import com.alibaba.druid.util.StringUtils;
import com.qf.air.service.ElasticsearchService;
import com.qf.air.util.R;
import com.qf.air.vo.ResultVO;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author 何星宇
 * @version V1.0
 * @Date 2021/11/8 11:29
 */

@Service
public class ElasticsearchServiceImpl implements ElasticsearchService {
    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Override
    public ResultVO findAirIndex(Integer page, Integer rows, Integer districtId, String monitoringStation, Date startTime, Date endTime) {
        //创建指定的request
        SearchRequest request = new SearchRequest();
        request.indices("air_index");

        //封装查询条件
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        //复合查询封装
        BoolQueryBuilder bool = QueryBuilders.boolQuery();

        //查询所有
        if (StringUtils.isEmpty(monitoringStation)&&startTime==null&&endTime==null){
            MatchAllQueryBuilder matchAllQuery = QueryBuilders.matchAllQuery();
            bool.must(matchAllQuery);
        }

        //区域id
        if (districtId!=null&&districtId!=0){
            MatchQueryBuilder districtIdBuilder = QueryBuilders.matchQuery("districtId", districtId);
            bool.must(districtIdBuilder);
        }
        //监测站
        if (!StringUtils.isEmpty(monitoringStation)){
            MatchQueryBuilder msBuilder = QueryBuilders.matchQuery("monitoringStation", monitoringStation);
            bool.must(msBuilder);

            HighlightBuilder highlightBuilder = new HighlightBuilder();
            highlightBuilder.fragmentSize(monitoringStation.length());
            highlightBuilder.preTags("<span style='color:red;'>");
            highlightBuilder.postTags("</span>");
            highlightBuilder.field("monitoringStation");
            //高亮显示
            sourceBuilder.highlighter(highlightBuilder);
        }
        //起始结束时间
        if (startTime!=null||endTime!=null){
            RangeQueryBuilder monitorTimeBuilder = QueryBuilders.rangeQuery("monitorTime");
            if (startTime!=null){
                monitorTimeBuilder.gte(startTime);
            }
            if (endTime!=null){
                monitorTimeBuilder.lte(endTime);
            }
            bool.must(monitorTimeBuilder);
        }

        //复合查询
        sourceBuilder.query(bool);
        //分页
        sourceBuilder.from((page-1)*rows);
        sourceBuilder.size(rows);
        //排序
        sourceBuilder.sort("_id", SortOrder.DESC);

        //封装到request
        request.source(sourceBuilder);

        //发送请求，得到响应
        SearchResponse response = null;
        try {
            response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //封装数据
        List result = new ArrayList();
        for (SearchHit hit : response.getHits().getHits()) {
            Map<String, Object> map = hit.getSourceAsMap();
            HighlightField highlightField = hit.getHighlightFields().get("monitoringStation");
            if (highlightField!=null){
                String value = highlightField.getFragments()[0].toString();
                map.put("monitoringStation",value);
            }
            result.add(map);
        }

        //封装数据
        return R.ok(result,response.getHits().getTotalHits().value);
    }
}
